package ronin.fx;

import java.util.*;
import java.applet.*;
import java.awt.*;
import java.awt.geom.*;
import ronin.graphics.*;

public class ParticleManager extends Object
{
	// main applet
	public Applet applet;
	
	public int maxAllowedSystems;
	public int maxAllowedParticles;
	
	// used by update to add systems to the render list
	public Rectangle2D viewable; 
	public LinkedList<ParticleSystem> renderList;
	
	// this is where all dead particles wait until resurection  time
	// as particle systems are added to the manager, particles are sent to the
	// system from this pool
	public LinkedList<Particle> particlePool;
	
	// This is where all the particle systems created are sent for 
	// update and rendering by the manager
	public LinkedList<ParticleSystem> particleSystems;
	
	public boolean debug = false;
	
	public ParticleManager(int maxAmountOfSystems, 
						   int maxAmountOfParticles, 
						   Applet a)
	{
		applet = a;
		viewable = new Rectangle2D.Double(0.0, 0.0, 600.0, 480.0);
		maxAllowedSystems   = maxAmountOfSystems;
		maxAllowedParticles = maxAmountOfParticles;
		
		particleSystems = new LinkedList<ParticleSystem>();
		particlePool 	= new LinkedList<Particle>();
		renderList		= new LinkedList<ParticleSystem>();
		
		setupParticlePool(maxAllowedParticles);
	}
	
	
	public void setupParticlePool(int numParticles)
	{
		for(int i = 0; i < numParticles; i++)
		{
			// create particles 
			Particle p = new Particle();
			
			// add them to the pool
			particlePool.add(p);
		}
		if(debug)System.out.println("PManager: pool = " + numParticles);
	}
	
	
	public void update()
	{
		if(debug)System.out.println("ParitclePool size = " + particlePool.size());
		
		ParticleSystem ps;
		
		for(int i=0; i<particleSystems.size(); i++)
		{
			ps = (ParticleSystem) particleSystems.get(i);
			
			if(ps.alive == false)
			{
				if(debug)System.out.println("Releasing system.");
				
				ps.releaseParticles();
				particleSystems.remove(i);
				continue;
			} 
			else
			{
				if(debug)System.out.println("Updating Sys");
				
				ps.update();
			}
			
			if(viewable.contains(ps.bounds) || 
			   viewable.intersects(ps.bounds))
			if(!renderList.contains(ps))
				renderList.add(ps);
		}
	}
	
	
	// renders all viewable systems
	public void render(Graphics2D g2d)
	{
		ParticleSystem ps;
		//System.out.println("renderList size = " + renderList.size());
		
		for(int i=0; i<renderList.size(); i++)
		{
			ps = (ParticleSystem) renderList.get(i);
			
			// test if still viewable, if so paint, 
			// else remove it from the viewable list
			if(viewable.contains(ps.bounds) ||
			   viewable.intersects(ps.bounds))
			{
				ps.paint(g2d);
			}
			else
			{
				renderList.remove(i);
			}
		}
		
	}
	
	
	// adds a particle system to the systems bay,
	// if systems.size() greater or equal to max allowed then false is returned 
	// to caller
	public boolean add(ParticleSystem ps)
	{
		if(particleSystems.size() >= maxAllowedSystems)return false;
		
		particleSystems.add(ps);
		
		return true;
	}
	
	
	public Image getImage(String file)
	{	
		return applet.getImage(applet.getCodeBase(), file);
	} 		
}